import 'package:flutter/material.dart';
import 'JvtdEmptyView.dart';
import 'JvtdLoadMoreView.dart';

typedef ItemWidgetBuild = Widget Function(BuildContext context, int position);
typedef LoadMoreCallback = void Function(int pageNum, int pageSize);

class EmptyConfig {
  final bool isHeaderAndFooter;
  final EmptyStatus emptyStatus;
  final BaseEmptyView emptyView;

  EmptyConfig({
    this.isHeaderAndFooter = false,
    @required this.emptyStatus,
    this.emptyView,
  });
}

class RefreshConfig {
  final RefreshCallback refreshCallback;

  RefreshConfig({
    @required this.refreshCallback,
  });
}

class LoadMoreConfig {
  final int pageSize;
  final LoadMoreStatus loadMoreStatus;
  final BaseLoadMoreView loadMoreView;
  final LoadMoreCallback loadMoreCallback;

  LoadMoreConfig({
    this.pageSize = 10,
    @required this.loadMoreStatus,
    this.loadMoreView,
    @required this.loadMoreCallback,
  });
}

class JvtdListView<T> extends StatefulWidget {
  RefreshConfig refreshConfig;
  LoadMoreConfig loadMoreConfig;
  EmptyConfig emptyConfig;
  List<Widget> headerList;
  List<Widget> footerList;
  List<T> listData;
  ItemWidgetBuild itemWidgetBuild;

  JvtdListView(
      {Key key,
      this.refreshConfig,
      this.loadMoreConfig,
      this.emptyConfig,
      this.headerList,
      this.footerList,
      @required this.listData,
      @required this.itemWidgetBuild})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => _JvtdListViewState();
}

class _JvtdListViewState extends State<JvtdListView> {
  ScrollController _scrollController = ScrollController();
  int _pageNum = 1;
  bool _isLoadMore = false;
  bool isLoading = false;

  @override
  void initState() {
    super.initState();
    if (widget.emptyConfig != null &&
        widget.emptyConfig.emptyStatus == EmptyStatus.LOADING) {
      isLoading = true;
    }
    if (widget.loadMoreConfig != null) {
      _scrollController.addListener(() {
        if (_scrollController.position.pixels ==
            _scrollController.position.maxScrollExtent) {
          _loadMore(false);
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      child: _isShowEmpty() ? _buildEmpty(context) : _buildList(context),
      onRefresh: _refresh,
    );
  }

  int _getHeaderCount() {
    return widget.headerList == null ? 0 : widget.headerList.length;
  }

  int _getFooterCount() {
    return widget.footerList == null ? 0 : widget.footerList.length;
  }

  int _getListCount() {
    if (widget.emptyConfig.isHeaderAndFooter) {
      return _isShowEmpty()
          ? 1
          : widget.listData.length +
              _getHeaderCount() +
              _getFooterCount() +
              _getLoadMoreCount();
    } else {
      if (_isShowEmpty()) {
        return 1;
      } else {
        return widget.listData.length +
            _getHeaderCount() +
            _getFooterCount() +
            _getLoadMoreCount();
      }
    }
  }

  int _getLoadMoreCount() {
    return widget.loadMoreConfig != null &&
            widget.loadMoreConfig.loadMoreStatus != LoadMoreStatus.FINISH
        ? 1
        : 0;
  }

  bool _isShowEmpty() {
    return widget.listData.length == 0 && widget.emptyConfig != null;
  }

  Widget _buildList(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, position) {
        return _buildWidget(context, position);
      },
      physics: AlwaysScrollableScrollPhysics(),
      itemCount: _getListCount(),
      controller: _scrollController,
    );
  }

  Widget _buildEmpty(BuildContext context) {
    return widget.emptyConfig.emptyView != null
        ? widget.emptyConfig.emptyView
        : JvtdEmptyView(
            emptyStatus: widget.emptyConfig.emptyStatus,
            onErrorPressed: () {
              _refresh();
            },
          );
  }

  Widget _buildWidget(BuildContext context, int position) {
    if (_isShowEmpty() && !widget.emptyConfig.isHeaderAndFooter) {
      return _buildEmpty(context);
    } else {
      if (position < _getHeaderCount()) {
        //头布局
        return widget.headerList.elementAt(position);
      } else if (position >=
          _getHeaderCount() + widget.listData.length + _getFooterCount()) {
        //加载更多布局
        return _buildLoadMore(context);
      } else if (position >= _getHeaderCount() + widget.listData.length) {
        //尾布局
        return widget.footerList
            .elementAt(position - (_getHeaderCount() + widget.listData.length));
      } else {
        //普通布局
        if (_isShowEmpty()) {
          return _buildEmpty(context);
        } else {
          return _buildItemWidget(context, position - _getHeaderCount());
        }
      }
    }
  }

  Widget _buildItemWidget(BuildContext context, int position) {
    return widget.itemWidgetBuild(context, position);
  }

  Widget _buildLoadMore(BuildContext context) {
    return widget.loadMoreConfig.loadMoreView != null
        ? widget.loadMoreConfig.loadMoreView
        : JvtdLoadMoreView(
            loadMoreStatus: widget.loadMoreConfig.loadMoreStatus,
            onErrorPressed: () {
              _loadMore(true);
            },
          );
  }

  @override
  void dispose() {
    super.dispose();
    _scrollController.dispose();
  }

  Future<Null> _refresh() async {
    _pageNum = 1;
    widget.refreshConfig.refreshCallback();
  }

  void _loadMore(bool error) {
    if (_isLoadMore) return;
    if (widget.loadMoreConfig.loadMoreStatus != LoadMoreStatus.END) {
      if (!error) {
        _pageNum++;
      }
      widget.loadMoreConfig
          .loadMoreCallback(_pageNum, widget.loadMoreConfig.pageSize);
    }
  }
}
